#pragma once
#include "lighttcp/sslclient.hpp"
#include "util.hpp"
class HTTPSRequest:public SSLClient{
	public:
	static const StringTable defaulttable;
	//返回false则这轮保留并重置状态 会阻塞后续数据
	typedef bool(*RequestCallback)(HTTPSRequest*,void*);
	typedef void(*TimeoutCallback)(HTTPSRequest*,void*);
	//响应限制 MAXKEYNUM针对字段
	static const unsigned int LENVERSION=8,LENTABLEKEY=32,LENTABLEVALUE=148,
	MAXKEYNUM=16,LENSTATUSCODE=4,LENSTATUSTEXT=LENTABLEKEY;
	//每次解析响应时更新
	StringTable value;
	//version使用memcmp比较
	char version[LENVERSION],statuscode[LENSTATUSCODE],statustext[LENSTATUSTEXT];
	/*自动拒绝不规范的响应报文 同一时间一个HTTPRequest只处理一个响应
	返回-1表示出错 0初始化成功 same==true则使用上一次建立的连接
	*/
	int request(const char* address,unsigned int port,const std::string& method,
	const std::string& url,const StringTable& header,void* data,size_t size,
	RequestCallback callback,void* arg,bool same);
	void getdata(void* buffer,size_t size,RequestCallback callback,void* arg);
	//invalidcallback在响应报文非法时调用 maxtime单位秒
	HTTPSRequest(TimeoutCallback tiemout,void* timeoutarg,
	RequestCallback invalidcallback,void* invalidarg,size_t maxtime=120);
	~HTTPSRequest()override;
	void print();
	static bool openlib();
	static void closelib();

	private:
	typedef struct{
		RequestCallback callback;
		void* arg;
		char* buffer;//默认nullptr 发送完后重置
	}RequestPack;
	static bool onrequest(HTTPSRequest*,void*);
	static bool onresponse(HTTPSRequest*,void*);
	enum instype{
		ins_version=0,ins_statuscode,ins_statustext,ins_statusend,
		ins_key,ins_keyhex1,ins_keyhex2,ins_value,ins_valuehex1,
		ins_valuehex2,ins_valueend,ins_resend
	};
	RequestCallback invalidcallback;
	RequestPack pack;
	void* invalidarg;
	size_t idcount;//每次请求时分配 只增不减
	unsigned int mode,headcount;
	char keybuffer[LENTABLEKEY],valuebuffer[LENTABLEVALUE];
	char got,hex;
	bool requested,firsttime;
};